package com.supermap.dataservice.rsm.service.impl;

import com.supermap.dataservice.rsm.RsmGridServiceImpl;
import com.supermap.dataservice.rsm.entity.DataInfo;
import com.supermap.dataservice.rsm.entity.ProductInfo;
import com.supermap.dataservice.rsm.service.NetCdfService;
import com.supermap.dataservice.rsm.service.RsmGridDataService;
import com.supermap.dataservice.util.JSONUtil;
import com.supermap.dataservice.util.NumberUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author xiaolu
 * @date 2018/9/5 上午11:38
 */
@Service
public class RsmGridDataServiceImpl implements RsmGridDataService {
    private Logger logger = LoggerFactory.getLogger(RsmGridDataServiceImpl.class);

    private final static String RSM_CONTENT = "SWRM";
    private final static String RSM_LEVEL = "LUG";
    private final static String RSM_UNIT = "CM";
    private final static String RSM_TYPE = "PD";
    private final static String RSM_ELEMENT = "RSM";

    @Autowired
    NetCdfService netcdfService;

    @Override
    public JSONUtil getRsmDataByLocation(double lon, double lat, String date, int deep, int valid, int adminCode) {
        ProductInfo p = new ProductInfo();
        p.setProductCategory(RSM_CONTENT);
        p.setProductAdminCode(adminCode);
        p.setProductDate(date);
        p.setProductLevel(RSM_LEVEL + deep + RSM_UNIT);
        p.setProductValid(NumberUtil.numToStringWith3Char(valid));
        p.setProductType(RSM_TYPE);
        p.setProductElement(RSM_ELEMENT + deep + RSM_UNIT);

        DataInfo dataInfo = null;
        String fileName = this.getFileName(p);
        String filePath = this.getFilePath(p);
        p.setProductFilePath(filePath + fileName);
        dataInfo = this.netcdfService.getDataInfo(p);
        Float value = getElementValue(dataInfo, lon, lat);

        JSONUtil result = new JSONUtil();
        result.setMsg("getRsmDataByLocation success！");
        result.setIsSuccess(true);
        result.setCode(200);
        result.setData(value);

        return result;
    }


    private String getFilePath(ProductInfo p) {
        StringBuffer sb = new StringBuffer();
        String content = p.getProductCategory();
        String element = p.getProductElement();
        String date = p.getProductDate();
        sb.append("/mnt/data/");
        sb.append(content).append("/").append(element).append("/").append(date.replace("-", "")).append("/");
        return sb.toString();
    }

    private String getFileName(ProductInfo p) {
        StringBuffer sb = new StringBuffer();
        String content = p.getProductCategory();
        String element = p.getProductElement();
        int adminCode = p.getProductAdminCode();
        String level = p.getProductLevel();
        String productType = p.getProductType();
        String valid = p.getProductValid();
        String date = p.getProductDate();
        sb.append(content).append("_").append(element).append("_").append(adminCode).append("_").append(level).append("_").append(productType).append("_").append(date.replace("-", "") + "080000").append("_").append(valid).append(".nc");
        return sb.toString();
    }

    /**
     * @return float
     * @throws
     * @Description: 根据经纬度获取要素值
     */
    private Float getElementValue(DataInfo p, double lon, double lat) {
        float left = p.getLeft();
        float right = p.getRight();
        float top = p.getTop();
        float bottom = p.getBottom();
        float dx = p.getDx();
        float dy = p.getDy();
        float[][] data = p.getValues();
        logger.info("目标数据经纬度范围：[left=" + left + ",right = " + right + ", bottom = " + bottom + ",top = " + top + "],目标数据分辨率：[dx = " + dx + ",dy = " + dy + "]");
        if (lon < left || lon > right || lat > top || lat < bottom) {
            logger.info("请求经纬度[lat=" + lat + ",lon=" + lon + "]不在目标范围。");
            return null;
        }

        //计算下标
        int x_index = (int) ((lon - left) / dx);
        int y_index = (int) ((lat - bottom) / dy);

        float value = data[y_index][x_index];
        return value;
    }
}
